' Stephen Toub
' Coded and published in January 2007 issue of MSDN Magazine 
' http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx


Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Resources
Imports System.Collections
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Diagnostics
Imports C4F.DevKit.PreviewHandler.PreviewHandlerFramework

Namespace C4F.DevKit.PreviewHandler.PreviewHandlers
    <PreviewHandler("MSDN Magazine Resources Preview Handler", ".resources", "{5679D180-540C-4db3-AF0C-97CDE2B7B5E7}"), ProgId("C4F.DevKit.PreviewHandler.PreviewHandlers.ResourcesPreviewHandler"), Guid("739972DC-DAD1-4e8c-BB82-113DE4B16B13"), ClassInterface(ClassInterfaceType.None), ComVisible(True)> _
    Public NotInheritable Class ResourcesPreviewHandler
        Inherits StreamBasedPreviewHandler
        Protected Overrides Function CreatePreviewHandlerControl() As PreviewHandlerControl
            Return New ResourcesPreviewHandlerControl()
        End Function

        Private NotInheritable Class ResourcesPreviewHandlerControl
            Inherits StreamBasedPreviewHandlerControl
            Private _listView As ListView
            Public Overrides Sub Load(ByVal previewStream As Stream)
                Dim listView As ListView = New ListView()

                listView.Columns.Add("File Name", -2)
                listView.Columns.Add("Data Type", -2)

                listView.Dock = DockStyle.Fill
                listView.BorderStyle = BorderStyle.None
                listView.FullRowSelect = True
                listView.HeaderStyle = ColumnHeaderStyle.Nonclickable
                listView.MultiSelect = False
                listView.View = View.Details

                AddHandler listView.DoubleClick, AddressOf anonDoubleClick
                Using reader As ResourceReader = New ResourceReader(previewStream)
                    For Each entry As DictionaryEntry In reader
                        Dim item As ListViewItem = New ListViewItem(New String() {entry.Key.ToString(), entry.Value.GetType().ToString()})
                        If Not (TypeOf entry.Value Is String OrElse TypeOf entry.Value Is Bitmap OrElse TypeOf entry.Value Is Stream OrElse TypeOf entry.Value Is Byte()) Then
                            item.ForeColor = SystemColors.GrayText
                        End If
                        item.Tag = entry
                        listView.Items.Add(item)
                    Next entry
                End Using

                Controls.Add(listView)
            End Sub
            Private Sub anonDoubleClick(ByVal sender As Object, ByVal e As EventArgs)
                Dim listView As ListView = CType(sender, ListView)
                If listView.SelectedItems.Count > 0 Then
                    Dim clicked As ListViewItem = listView.SelectedItems(0)
                    Dim entry As DictionaryEntry = CType(clicked.Tag, DictionaryEntry)

                    If TypeOf entry.Value Is Bitmap Then
                        Dim bmp As Bitmap = CType(entry.Value, Bitmap)
                        Dim tempPath As String = CreateTempPath(".png")
                        bmp.Save(tempPath, ImageFormat.Png)
                        Process.Start(tempPath)
                    ElseIf TypeOf entry.Value Is String Then
                        Dim str As String = CStr(entry.Value)
                        Dim tempPath As String = CreateTempPath(".txt")
                        File.WriteAllText(tempPath, str)
                        Process.Start(tempPath)
                    ElseIf TypeOf entry.Value Is Stream OrElse TypeOf entry.Value Is Byte() Then
                        Dim buffer As Byte() = Nothing
                        If TypeOf entry.Value Is Byte() Then
                            buffer = CType(entry.Value, Byte())
                        Else
                            Try
                                Dim valueStream As Stream = CType(entry.Value, Stream)
                                valueStream.Position = 0
                                buffer = New Byte(CInt(valueStream.Length - 1)) {}
                                valueStream.Read(buffer, 0, buffer.Length)
                            Catch e1 As IOException
                            Catch e2 As NotSupportedException
                            End Try
                        End If
                        If Not buffer Is Nothing Then
                            Using sfd As SaveFileDialog = New SaveFileDialog()
                                If sfd.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                                    File.WriteAllBytes(sfd.FileName, buffer)
                                End If
                            End Using
                        End If
                    End If
                End If
            End Sub

        End Class
    End Class
End Namespace